﻿#include <QPainter>
#include <QPen>
#include <QBrush>
#include <QColor>

#include "CPlcItemContact.h"

CPlcItemContact::CPlcItemContact(const QRectF &rect,
                                 const int8_t type,
                                 const QString &str,
                                 IPlcBaseItem *parent)
    : IPlcBaseItem(parent)
{
    mVariableNum  = str;
    mSelectActive = false;
    mSwitchOn     = false;
    mLastSwitchOn = false;
    mType         = type;
    mBranch       = NULL;
    setRect(rect);
}

CPlcItemContact::~CPlcItemContact()
{
    //如果当前为选中状态
    if (mSelectActive) setOnlySelectItem(NULL);
}

QRectF CPlcItemContact::getRect()
{
    return mRect;
}

void CPlcItemContact::setRect(const QRectF &rect)
{
    if (mRect == rect) return;
    //准备调整几何边界
    prepareGeometryChange();
    mRect         = rect;
    mBoundingRect = QRectF();
    // 缩放比例
    mdWidthScale  = mRect.width() / 65.0;
    mdheightScale = mRect.height() / 55.0;
    //重绘
    update();
}

IPlcBaseItem *CPlcItemContact::getBranch()
{
    return mBranch;
}

void CPlcItemContact::setBranch(IPlcBaseItem *item)
{
    mBranch = item;
}

void CPlcItemContact::deleteBranch()
{
    mBranch = NULL;
}

QString CPlcItemContact::getVariableNum()
{
    return mVariableNum;
}

void CPlcItemContact::setVariableNum(const QString &str)
{
    if (mVariableNum == str) return;
    //重新设置变量编号
    mVariableNum = str;
    //重绘
    update();
}

void CPlcItemContact::setSelectActive(bool status)
{
    //复位之前选中的图元
    if (this != getOnlySelectItem())
    {
        if (getOnlySelectItem() != NULL)
            getOnlySelectItem()->setSelectActive(false);
    }

    if (mSelectActive == status) return;

    mSelectActive = status;
    status ? setOnlySelectItem(this) : setOnlySelectItem(NULL);
    //重绘图元
    update();
}

void CPlcItemContact::setSwitchOn(bool value)
{
    if (mSwitchOn == value) return;

    mSwitchOn = value;
    //重绘图元
    update();
}

void CPlcItemContact::setLastSwitchOn(bool value)
{
    if (mLastSwitchOn == value) return;

    mLastSwitchOn = value;
    //重绘图元
    update();
}

int8_t CPlcItemContact::getItemType()
{
    return mType;
}

void CPlcItemContact::setItemType(int8_t type)
{
    if (mType == type) return;
    mType = type;
    update();
}

QRectF CPlcItemContact::boundingRect() const
{
    if (mBoundingRect.isNull()) mBoundingRect = mRect;

    return mBoundingRect;
}

void CPlcItemContact::paint(QPainter *painter,
                            const QStyleOptionGraphicsItem *option,
                            QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    // 设置反走样
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->setRenderHint(QPainter::TextAntialiasing, true);

    QBrush blackBrush(Qt::black);
    QBrush blueBrush(QColor(2, 167, 240));
    QPen pen;
    //绘制选中状态
    if (mSelectActive)
    {
        //设置画笔样式为虚线
        pen.setStyle(Qt::DashLine);
        pen.setWidth(1);         //线宽1
        pen.setBrush(Qt::red);   //颜色红色
        painter->setPen(pen);
        painter->drawRect(mRect);   //画矩形
    }

    //坐标相关计算
    double x1 = mRect.left();                         //最左边导线点
    double x2 = mRect.left() + mdWidthScale * 27.5;   //元件左边点
    double x3 = mRect.left() + mdWidthScale * 37.5;   //元件右边点
    double x4 = mRect.right();

    double y1 = mRect.top() + mdheightScale * 35;   //连接线点
    double y2 = mRect.top() + mdheightScale * 25;   //元件顶点
    double y3 = mRect.top() + mdheightScale * 45;   //元件底点

    //先画两条竖线，固定是黑色的
    pen.setStyle(Qt::SolidLine);
    pen.setWidth(0);
    pen.setBrush(blackBrush);   //颜色
    painter->setPen(pen);
    //两条竖线
    painter->drawLine(x2, y2, x2, y3);   //画直线
    painter->drawLine(x3, y2, x3, y3);   //画直线
                                         //绘制变量编号
    QFont font;
    font.setPixelSize(13);   //字体像素大小
    painter->setFont(font);
    painter->drawText(QRectF(mRect.left() + 7.5 * mdWidthScale, mRect.top(),
                             50 * mdWidthScale, 25 * mdheightScale),
                      Qt::AlignCenter, mVariableNum);

    //根据前置信号状态，画前面一条横线
    if (mLastSwitchOn)
    {
        pen.setBrush(blueBrush);   //颜色
    }
    else
    {
        pen.setBrush(blackBrush);   //颜色
    }
    painter->setPen(pen);
    painter->drawLine(x1, y1, x2, y1);   //画直线

    //绘制信号接通状态
    if (mSwitchOn)
    {
        pen.setColor(QColor(qRgb(2, 167, 240)));   //颜色
        painter->setPen(pen);
        painter->setBrush(blueBrush);
        painter->drawRect(
            QRectF(x2, y2, mdWidthScale * 9, mdheightScale * 19));   //画矩形
        painter->drawLine(x3, y1, x4, y1);                           //画直线
    }
    else
    {
        pen.setBrush(blackBrush);   //颜色
        painter->setPen(pen);
        painter->drawLine(x3, y1, x4, y1);   //画直线
    }
    //按类型设置上升沿、下降沿
    pen.setBrush(blackBrush);   //颜色
    painter->setPen(pen);
    switch (mType)
    {
    case plc::CloseContact:
        painter->drawLine(x3, y2, x2, y3);   //画直线
        break;
    case plc::Pulse:
    {
        //画上升箭头
        double x1 = mRect.left() + mdWidthScale * 32.5;   //箭头中间x轴
        double y1 = mRect.top() + mdheightScale * 26;     //箭头顶点
        double y2 = mRect.top() + mdheightScale * 44;     //箭头底点
        painter->drawLine(x1, y1, x1, y2);                //画竖线
        painter->drawLine(x1, y1, x1 - mdWidthScale * 2,
                          y1 + mdheightScale * 4);   //箭头
        painter->drawLine(x1, y1, x1 + mdWidthScale * 2,
                          y1 + mdheightScale * 4);   //箭头
        break;
    }
    case plc::Falling:
    {
        //画下降箭头
        double x1 = mRect.left() + mdWidthScale * 32.5;   //箭头中间x轴
        double y1 = mRect.top() + mdheightScale * 26;     //箭头顶点
        double y2 = mRect.top() + mdheightScale * 44;     //箭头底点
        painter->drawLine(x1, y1, x1, y2);                //画竖线
        painter->drawLine(x1, y2, x1 - mdWidthScale * 2,
                          y2 - mdheightScale * 4);   //箭头
        painter->drawLine(x1, y2, x1 + mdWidthScale * 2,
                          y2 - mdheightScale * 4);   //箭头
        break;
    }
    }
}

bool CPlcItemContact::getEditEnb()
{
    return true;
}

bool CPlcItemContact::getSelectActiveEnb()
{
    return true;
}

bool CPlcItemContact::getSelectActive()
{
    return mSelectActive;
}
